home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Unix / process_pedigree / pedigree.c next >
Encoding:
C/C++ Source or Header  |  1993-08-03  |  3.5 KB  |  148 lines

  1. /* pedigree: show process ancestry
  2.  * Eric P. Scott, San Francisco State University, July 1993
  3.  *    added -h switch -- Bruce Gingery bruce@TotSysSoft.com Wed Aug  4 03:17:30 MDT 1993
  4.  
  5.  *
  6.  * Compile on 2.x:
  7.  *   cc -o pedigree -s -object -O -bsd pedigree.c
  8.  * Compile on 3.0:
  9.  *   cc -o pedigree -s -object -O -bsd -DNX_COMPILER_RELEASE_3_0 pedigree.c
  10.  * Compile on 3.1:
  11.  *   cc -o pedigree -s -object -O2 -bsd -fno-builtin pedigree.c
  12.  */
  13. #include <stdio.h>
  14. #include <sys/errno.h>
  15. #ifdef __STRICT_BSD__
  16. #include <strings.h>
  17. #else
  18. #include <string.h>
  19. #endif
  20. #include <sys/types.h>
  21. #include <sys/dir.h>
  22. #include <sys/stat.h>
  23. #ifndef NX_COMPILER_RELEASE_3_0
  24. #include <sys/table.h>
  25. #else
  26. /*
  27.  * Mach Operating System
  28.  * Copyright (c) 1986 Carnegie-Mellon University
  29.  * All rights reserved.  The CMU software License Agreement specifies
  30.  * the terms and conditions for use and redistribution.
  31.  */
  32. #define    TBL_PROCINFO        10    /* index by proc table slot */
  33. /*
  34.  *    TBL_PROCINFO data layout
  35.  */
  36. #define    PI_COMLEN    19    /* length of command string */
  37. struct tbl_procinfo
  38. {
  39.     int        pi_uid;        /* user ID */
  40.     int        pi_pid;        /* proc ID */
  41.     int        pi_ppid;    /* parent proc ID */
  42.     int        pi_pgrp;    /* proc group ID */
  43.     int        pi_ttyd;    /* controlling terminal number */
  44.     int        pi_status;    /* process status: */
  45. #define    PI_EMPTY    0        /* no process */
  46. #define    PI_ACTIVE    1        /* active process */
  47. #define    PI_EXITING    2        /* exiting */
  48. #define    PI_ZOMBIE    3        /* zombie */
  49.     int        pi_flag;    /* other random flags */
  50.     char    pi_comm[PI_COMLEN+1];
  51.                 /* short command name */
  52. };
  53. #endif
  54.  
  55. main(argc, argv)
  56. int argc;
  57. char *argv[];
  58. {
  59.     extern int errno;
  60.     int chrdev();
  61.     register struct direct *d, **dp;
  62.     register int i;
  63.     int pid, n;
  64.     struct tbl_procinfo pi;
  65.     struct direct **df;
  66.     dev_t lastd;
  67.     char tty[4];
  68.  
  69.     if (argc<1||argc>2) {
  70.         (void)fprintf(stderr, "Usage: %s [pid]\n", *argv);
  71.         exit(1);
  72.     }
  73.     if (argc==2) {
  74.           if (!strcmp(argv[1],"-h")) {
  75.               (void)fprintf(stderr, "Usage: %s [pid]\n", *argv);
  76.               exit(1);
  77.          }
  78.         pid=atoi(argv[1]);
  79.         if (kill(pid, 0)<0&&errno!=EPERM) {
  80.             perror(argv[1]);
  81.             exit(1);
  82.         }
  83.     }
  84.     else pid=getpid();
  85.     if (chdir("/dev")<0) {
  86.     perror("chdir");
  87.     exit(1);
  88.     }
  89.     if ((n=scandir(".", &df, chrdev, alphasort))<0) {
  90.     (void)fputs("scandir() failed\n", stderr);
  91.     exit(1);
  92.     }
  93.     lastd=(dev_t)-1;
  94.     tty[0]='?', tty[1]='\0'; tty[2]='\0', tty[3]='\0';
  95.     (void)fputs("  UID   PID  PPID  PGRP TT COMMAND\n", stdout);
  96.     for (;;) {
  97.     if (table(TBL_PROCINFO, pid, (char *)&pi, 1,
  98.         sizeof pi)==1&&pi.pi_status==PI_ACTIVE) {
  99.         if (pi.pi_ttyd!=lastd) {
  100.         if (pi.pi_ttyd<0) tty[0]='?', tty[1]='\0';
  101.         else {
  102.             dp=df;
  103.             i=n; do {
  104.             d= *dp++;
  105.             if (*(dev_t *)&d->d_ino==(dev_t)pi.pi_ttyd) {
  106.                 if (d->d_namlen>3&&!strncmp(d->d_name, "tty", 3))
  107.                 (void)strncpy(tty, d->d_name+3, 3); 
  108.                 else {
  109.                 tty[0]=d->d_name[0], tty[1]=d->d_name[1];
  110.                 tty[2]='\0';
  111.                 }
  112.                 goto x;
  113.             }
  114.             } while (--i>0);
  115.             tty[0]='?', tty[1]='?'; tty[2]='\0';
  116.         }
  117.         x:
  118.         lastd=pi.pi_ttyd;
  119.         }
  120.         (void)printf("%5d %5d %5d %5d %-3s%.*s\n", pi.pi_uid,
  121.         pid, pi.pi_ppid, pi.pi_pgrp, tty,
  122.         PI_COMLEN, pi.pi_comm);
  123.     }
  124.     else {
  125.         (void)fputs("something went wrong\n", stderr);
  126.         exit(1);
  127.     }
  128.     if (pid<=1) break;
  129.     pid=pi.pi_ppid;
  130.     }
  131.     exit(0);
  132. }
  133.  
  134. int chrdev(d)
  135. struct direct *d;
  136. {
  137.     struct stat st;
  138.  
  139.     if (d->d_name[0]=='t'||(d->d_name[0]=='c'&&d->d_name[1]=='o')) {
  140.         d->d_name[d->d_namlen]='\0';
  141.         if (stat(d->d_name, &st)>=0&&(st.st_mode&S_IFMT)==S_IFCHR) {
  142.             *(dev_t *)&d->d_ino=st.st_rdev;
  143.             return(1);
  144.         }
  145.     }
  146.     return(0);
  147. }
  148.